import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

// 2D点类（存储三个值，但判断用前两个）
class Point2D {
    double x, y, z;  // x=lon/x, y=lat/y, z=alt/z (忽略z)

    public Point2D(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    @Override
    public String toString() {
        return "(" + x + ", " + y + ", " + z + ")";
    }
}

public class Main {
    // 射线交叉算法：判断点是否在多边形内（不包括边界）
    private static boolean isPointInPolygon(Point2D point, List<Point2D> polygon) {
        boolean inside = false;
        int n = polygon.size();
        double px = point.x;
        double py = point.y;
        for (int i = 0, j = n - 1; i < n; j = i++) {
            Point2D pi = polygon.get(i);
            Point2D pj = polygon.get(j);
            if ((pi.y > py) != (pj.y > py) && 
                (px < pi.x + (pj.x - pi.x) * (py - pi.y) / (pj.y - pi.y + 1e-10))) {
                inside = !inside;
            }
        }
        return inside;
    }

    // 解析输入字符串为Point2D
    private static Point2D parsePoint(String input, String coordType) throws IllegalArgumentException {
        String[] parts = input.split(",");
        if (parts.length != 3) {
            throw new IllegalArgumentException("需输入3个数字，用逗号分隔（如: 39.910,116.390,0）。");
        }
        double a = Double.parseDouble(parts[0].trim());
        double b = Double.parseDouble(parts[1].trim());
        double c = Double.parseDouble(parts[2].trim());
        if (coordType.equals("latlon")) {
            return new Point2D(b, a, c);  // (lon, lat, alt)
        } else {
            return new Point2D(a, b, c);  // (x, y, z)
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("欢迎使用交互式2D GNSS电子围栏判断工具 (Java版，射线交叉算法)！");

        // 步骤1: 选择坐标类型
        System.out.print("输入坐标类型 (latlon 为经纬高, xyz 为XYZ): ");
        String coordType = scanner.nextLine().trim().toLowerCase();
        if (!coordType.equals("latlon") && !coordType.equals("xyz")) {
            System.out.println("无效类型！默认使用latlon。");
            coordType = "latlon";
        }
        String label = coordType.equals("latlon") ? "经纬高 (lat,lon,alt)" : "XYZ (x,y,z)";

        // 步骤2: 输入围栏边界点
        System.out.println("\n输入围栏边界点（" + label + "格式，用逗号分隔）。输入至少3个点，按顺序形成闭合多边形。");
        System.out.println("每次输入一个点，回车确认；输入 'done' 结束。确保点顺序顺时针/逆时针，不自交！");
        List<Point2D> fencePoints = new ArrayList<>();
        while (true) {
            System.out.print("围栏点: ");
            String inp = scanner.nextLine().trim();
            if (inp.toLowerCase().equals("done")) break;
            try {
                Point2D point = parsePoint(inp, coordType);
                fencePoints.add(point);
                System.out.println("添加点: " + point);
            } catch (Exception e) {
                System.out.println("错误: " + e.getMessage() + " 请重新输入。");
            }
        }

        if (fencePoints.size() < 3) {
            System.out.println("错误: 至少需要3个点形成多边形！程序退出。");
            return;
        }
        System.out.println("\n围栏定义完成！多边形点: " + fencePoints);

        // 步骤3: 输入测试点并判断
        List<Point2D> testPoints = new ArrayList<>();
        List<Boolean> insideStatus = new ArrayList<>();
        System.out.println("\n现在输入测试点（相同格式）。每次一个点，回车确认；输入 'done' 结束。");
        while (true) {
            System.out.print("测试点: ");
            String inp = scanner.nextLine().trim();
            if (inp.toLowerCase().equals("done")) break;
            try {
                Point2D point = parsePoint(inp, coordType);
                boolean isInside = isPointInPolygon(point, fencePoints);
                String status = isInside ? "在围栏内部" : "在围栏外部";
                System.out.println("点 " + point + ": " + status);
                testPoints.add(point);
                insideStatus.add(isInside);
            } catch (Exception e) {
                System.out.println("错误: " + e.getMessage() + " 请重新输入。");
            }
        }

        // 步骤4: 简单文本可视化（无图形）
        if (!testPoints.isEmpty()) {
            System.out.println("\n文本可视化（简化）：");
            for (int i = 0; i < testPoints.size(); i++) {
                String color = insideStatus.get(i) ? "绿色 (内部)" : "红色 (外部)";
                System.out.println("测试点" + (i+1) + ": " + testPoints.get(i) + " - " + color);
            }
        } else {
            System.out.println("无测试点，无可视化。");
        }

        System.out.println("程序结束。");
    }
}